package com.cxs.distributeddemo.slice;

import com.cxs.distributeddemo.ResourceTable;
import com.cxs.distributeddemo.been.Contacter;
import com.cxs.distributeddemo.component.ContactComponent;
import com.cxs.distributeddemo.provider.ContactProvider;
import com.cxs.distributeddemo.util.DeviceUtils;
import com.cxs.distributeddemo.util.KvStoreUtils;
import ohos.aafwk.ability.AbilitySlice;
import ohos.aafwk.content.Intent;
import ohos.agp.components.Component;
import ohos.agp.components.ListContainer;
import ohos.agp.utils.LayoutAlignment;
import ohos.agp.window.dialog.CommonDialog;
import ohos.agp.window.dialog.ToastDialog;
import ohos.data.distributed.common.*;
import ohos.data.distributed.device.DeviceFilterStrategy;
import ohos.data.distributed.device.DeviceInfo;
import ohos.data.distributed.user.SingleKvStore;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

public class ContactSlice extends AbilitySlice {
    List<Contacter> contactArray;
    ContactProvider contactAdapter;
    ListContainer listContainer;
    KvManager manager;
    SingleKvStore kvStore;

    @Override
    protected void onStart(Intent intent) {
        super.onStart(intent);
        super.setUIContent(ResourceTable.Layout_ability_contact);

        initList();
        initDB();
        setContactArray();

        findComponentById(ResourceTable.Id_addContact).setClickedListener(c -> {
            getUITaskDispatcher().asyncDispatch(new Runnable() {
                @Override
                public void run() {
                    showDialog(null, null, new ContactComponent.DialogCallback() {
                        @Override
                        public void result(String name, String phone) {
                            // phone是唯一的，姓名不唯一
                            // 所以phone为key
                            kvStore.putString(phone, name);
                        }
                    });
                }
            });

        });

        findComponentById(ResourceTable.Id_sync).setClickedListener(c -> {
            syncContact();
        });
    }

    /*
        初始化分布式数据库
     */
    void initDB() {
        manager = KvStoreUtils.createManager(this);
        // 分布式数据库
        kvStore = KvStoreUtils.createDB(manager);
        // 订阅数据库变化
        subScribeDB(kvStore);
    }

    void subScribeDB(SingleKvStore kvStore) {
        kvStore.subscribe(SubscribeType.SUBSCRIBE_TYPE_LOCAL, new KvStoreObserver() {
            @Override
            public void onChange(ChangeNotification changeNotification) {
                System.out.println("onChange");
                getUITaskDispatcher().delayDispatch(new Runnable() {
                    @Override
                    public void run() {

                        setContactArray();
                    }
                }, 0);
            }
        });
    }

    void setContactArray() {
        List<Entry> entries = kvStore.getEntries("");
        contactArray.clear();
        for (Entry entry : entries) {
            // key:手机号码（唯一）
            // value: 姓名（不唯一）
            contactArray.add(new Contacter(entry.getValue().getString(), entry.getKey()));
        }
        contactAdapter.notifyDataChanged();
    }

    void syncContact() {

        kvStore.registerSyncCallback(new SyncCallback() {
            @Override
            public void syncCompleted(Map<String, Integer> map) {

                getUITaskDispatcher().asyncDispatch(() -> {
                    setContactArray();
                });
                kvStore.unRegisterSyncCallback();
            }
        });
        List<String> deviceIdList = DeviceUtils.getDeviceList();
        kvStore.sync(deviceIdList, SyncMode.PUSH_PULL);
    }
    /*
        初始化ListContainer
     */
    void initList() {
        Component component = findComponentById(ResourceTable.Id_listContainer);
        if (component instanceof ListContainer) {
            listContainer = (ListContainer)component;
            contactArray = new ArrayList<>();
            contactAdapter = new ContactProvider(this, contactArray);
            // 把适配器装入ListContainer
            listContainer.setItemProvider(contactAdapter);
            // 设置适配器的事件回调接口
            contactAdapter.setAdapterClickListener(aListener);
        }
    }

    /*
        实现接口的编辑/删除方法
     */
    ContactProvider.AdapterClickListener aListener = new ContactProvider.AdapterClickListener() {
        @Override
        public void edit(int position) {
            Contacter contacter = contactArray.get(position);
            showDialog(contacter.getName(), contacter.getPhone(),
                    (name, phone) -> {
                        kvStore.delete(contacter.getPhone());
                        kvStore.putString(phone, name);
                    });
        }

        @Override
        public void delete(int position) {
            kvStore.delete(contactArray.get(position).getPhone());
        }
    };

    /*
        显示增加/编辑对话框
     */
    private void showDialog(String strName, String strPhone, ContactComponent.DialogCallback dialogCallback) {

        CommonDialog commonDialog = new CommonDialog(this);
        ContactComponent contactComponent = new ContactComponent(this);
        contactComponent.initData(strName, strPhone);
        // 设置回调事件
        contactComponent.setDialogCallback(new ContactComponent.DialogCallback() {
            @Override
            public void result(String name, String phone) {
                if (name.isEmpty() || phone.isEmpty()) {
                    showTip("姓名和手机号码必填");
                }
                if (dialogCallback != null) {
                    dialogCallback.result(name, phone);
                }
                commonDialog.remove();
            }
        });
        commonDialog.setAlignment(LayoutAlignment.CENTER);
        // 把自定义对话框添加到CommonDialog里
        commonDialog.setContentCustomComponent(contactComponent);
        // 显示CommonDialog
        commonDialog.show();
    }

    private void showTip(String message) {
        new ToastDialog(this)
                .setAlignment(LayoutAlignment.CENTER)
                .setText(message)
                .show();
    }

}
